#include "xen/renderer/perspective_camera_controller.hpp"

namespace Xen {

PerspectiveCameraController::PerspectiveCameraController(float fovy, float aspect, float znear, float zfar)
:camera_(fovy, aspect, znear, zfar) {
}

void PerspectiveCameraController::OnUpdate(TimeStep ts) {
    float rotation_y = camera_.GetRotation().y;
    glm::vec3 back = glm::rotate(glm::mat4(1.0), glm::radians(rotation_y), glm::vec3(0, 1, 0)) * glm::vec4(0, 0, 1, 1);
    glm::vec3 right = glm::cross(glm::vec3(0, 1, 0), back);

    if (Input::IsKeyPressed(XEN_A)) {
        position_ -= right * (speed_ * ts);
    }
    if (Input::IsKeyPressed(XEN_D)) {
        position_ += right * (speed_ * ts);
    }
    if (Input::IsKeyPressed(XEN_W)) {
        position_ -= back * (speed_ * ts);
    }
    if (Input::IsKeyPressed(XEN_S)) {
        position_ += back * (speed_ * ts);
    }
    camera_.SetPosition(position_.x, position_.y, position_.z);
}

void PerspectiveCameraController::OnEvent(Event& e) {
    Xen::EventDispatcher dispatcher(e);
    dispatcher.Dispatch<Xen::MouseMotionEvent>(BIND_EVENT_FN(PerspectiveCameraController::onMouseMotion));
}

bool PerspectiveCameraController::onMouseMotion(Xen::MouseMotionEvent& e) {
    if (Input::IsMouseButtonPressed(MouseButton::LEFT)) {
        rotation_.y -= e.GetOffsetX() * speed_ * 3;
    }
    camera_.SetRotation(rotation_);
    return false;
}

}
